package com.example.aigc_education.service.impl;

import cn.hutool.core.lang.UUID;
import com.example.aigc_education.common.BusinessException;
import com.example.aigc_education.constant.ChatConstants;
import com.example.aigc_education.domain.request.ChatAiContentRequest;
import com.example.aigc_education.integration.impl.ChatServiceIntegrationImpl;
import com.example.aigc_education.integration.request.ChatMessageRequest;
import com.example.aigc_education.rpc.api.ChatServiceProto;
import com.example.aigc_education.service.AlgoService;
import com.example.aigc_education.utils.*;
import io.grpc.stub.StreamObserver;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import javax.annotation.Resource;

import java.util.Objects;
import java.util.Optional;


@Service
@Slf4j
public class AlgoServiceImpl implements AlgoService {

    @Resource
    private ChatServiceIntegrationImpl chatServiceIntegration;


    @Override
    public SseEmitter connect(Long messageId) {

        return Optional.ofNullable(messageId)
                .map(id -> {
                    log.info("AlgoServiceImpl-connect messageId is not null");
                    return SseServer.createConnect(id);
                })
                .orElseGet(() -> {
                    log.info("AlgoServiceImpl-connect messageId is null");
                    throw new BusinessException("连接失败");
                });
    }

    @Override
    public ChatMessageRequest chat(ChatAiContentRequest request) {
        if (StringUtils.isEmpty(request.getContent()) || StringUtils.isEmpty(request.getConvId())) {
            log.info("AlgoServiceImpl-chat content is empty, request:{}", JsonUtils.toJson(request));
            throw new BusinessException("AI对话内容为空");
        }
        Long messageId = System.currentTimeMillis();
        // 未连接进行连接
        SseEmitter sseEmitter = Optional.ofNullable(SseServer.getConnect(messageId))
                .orElseGet(() -> {
                    log.info("AlgoServiceImpl-chat sseEmitter is null, create new connect");
                    return SseServer.createConnect(messageId);
                });
//        SseEmitter sseEmitter = SseServer.getConnect(messageId);



        ChatMessageRequest.ChatMessageRequestBuilder rpcRequest = ChatMessageRequest.builder()
                .messageId(String.valueOf(messageId))
                .content(request.getContent())
                .role(ChatMessageRequest.Role.USER)
                .userId(Objects.requireNonNull(SecurityUtils.getUserId()).toString())
                .convId(request.getConvId())
                .chunkResp(true);


        chatServiceIntegration.stream(rpcRequest.build(), new StreamObserver<ChatServiceProto.ChatMessage>() {
            @Override
            public void onNext(ChatServiceProto.ChatMessage chatMessage) {
                try {
                    // Todo:如果是StreamObserver onCompleted后，那么sse也会被complete，则只需输出chatMessage.getContent
                    log.info("AlgoServiceImpl-chat onNext chatMessage:{}", chatMessage.toString());
                    ChatMessageRequest response = ChatMessageRequest.builder()
                            .messageId(chatMessage.getMessageId())
                            .content(chatMessage.getContent())
                            .role(ChatMessageRequest.Role.AI)
                            .userId(chatMessage.getUserId())
                            .convId(chatMessage.getConvId())
                            .chunkResp(chatMessage.getChunkResp())
                            .build();
                    sseEmitter.send(JsonUtils.toJson(response));
                } catch (Exception e) {
                    // Todo: 这里会出现什么情况的error
                    log.error("AlgoServiceImpl-chat send message error: {}", e.getMessage());
                    sseEmitter.completeWithError(e);

                }
            }

            @Override
            public void onError(Throwable throwable) {
                // Todo: 这里如果error的话那么要提醒用户重新调用程序
                log.error("AlgoServiceImpl-chat onError, error:{}", throwable.getMessage());
                sseEmitter.completeWithError(throwable);
            }

            @Override
            public void onCompleted() {
                log.info("AlgoServiceImpl-chat onCompleted");
                sseEmitter.complete();
            }
        });

        return rpcRequest.build();
    }

}
